﻿using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using CSSoft.VNTower.Domain;
using Microsoft.SharePoint;
using CSSoft;
using Telerik.Web.UI;
using System.Linq;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using Microsoft.SharePoint.WebControls;
using System.Net.Mail;

namespace CSSoft.VNTower.DailyReport
{
    public partial class DailyReportUserControl : UserControl
    {
        private DailyReportItem _data;
        public DailyReportItem Data
        {
            get
            {
                if (ViewState["DailyReportItem"] == null)
                    ViewState["DailyReportItem"] = new DailyReportItem();
                _data = (DailyReportItem)ViewState["DailyReportItem"];
                return _data;
            }
            set
            {
                ViewState["DailyReportItem"] = value;
            }
        }
        private List<ProjectItem> _workingProjects;
        public List<ProjectItem> WorkingProjects
        {
            get
            {
                if (ViewState["WorkingProjects"] == null)
                    ViewState["WorkingProjects"] = new List<ProjectItem>();
                _workingProjects = (List<ProjectItem>)ViewState["WorkingProjects"];
                return _workingProjects;
            }
            set
            {
                ViewState["WorkingProjects"] = value;
            }
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            SubmitMessage.Text = "";
            ActionMessage.Text = "";
            if (!Page.IsPostBack)
            {
                #region Read data
                DailyReportItem data = new DailyReportItem();
                //Load Daily Report
                bool addNew = true;
                if (Request.QueryString["_Id"] != null) //ReportID
                {
                    try
                    {
                        int reportId = CS2Convert.ToInt(Request.QueryString["_Id"]);
                        SPList listDailyReport = CS2Web.GetList(Constants.LIST_DAILY_REPORT);
                        SPListItem itemDailyReport = listDailyReport.GetItemById(reportId);
                        data.GetItem(itemDailyReport);
                        addNew = false;
                    }
                    catch { }
                }
                else
                {
                    SPList listDailyReport = CS2Web.GetList(Constants.LIST_DAILY_REPORT);
                    SPQuery query = new SPQuery();
                    query.Query = String.Format(@"<Where>
                        <And>
                            <Eq>
                            <FieldRef Name='Title' />
                            <Value Type='Text'>{0}</Value>
                            </Eq>
	                    <Eq>
		                    <FieldRef Name='Author' LookupId='TRUE'/>
		                    <Value Type='User'>{1}</Value>
	                    </Eq>
                        </And>
                    </Where>", DateTime.Today.ToString(Constants.DATE_FORMAT), CS2Web.CurrentUser.ID);
                    SPListItemCollection items = listDailyReport.GetItems(query);
                    if (CS2SPQueryBuilder.HasItems(items))
                    {
                        data.GetItem(items[0]);
                        addNew = false;
                    }
                }
                if (addNew)
                {
                    data.Date = DateTime.Today;
                    data.Reporter = new UserItem { User = CS2Web.CurrentUser };
                }
                LoadDataReport(data);
                #endregion

                #region Read Permission
                //Reporter Controls
                if (CS2Web.CurrentUser.ID != data.Reporter.Id)
                {
                    EmailTo.Enabled = false;
                    EmailCC.Enabled = false;
                    Note.Enabled = false;
                    Project.Enabled = false;
                    ReportFiles.Enabled = false;
                    Upload.Visible = false;
                    //Files grid
                    if (data.ReportFiles.Count > 0)
                    {
                        SPList listProjects = CS2Web.GetList(Constants.LIST_PROJECTS);
                        SPQuery queryProjects = new SPQuery();
                        queryProjects.Query = String.Format(@"<Where>
	                        <Eq>
		                        <FieldRef Name='Members' LookupId='TRUE'/>
		                        <Value Type='User'>{0}</Value>
	                        </Eq>
                        </Where>", CS2Web.CurrentUser.ID);

                        SPListItemCollection itemProjects = listProjects.GetItems(queryProjects);
                        if (!CS2SPQueryBuilder.HasItems(itemProjects))
                        {
                            Files.Enabled = false;
                            Files.Columns[0].Visible = false; //Edit
                            Files.Columns[5].Visible = false; //Delete
                            Submit.Visible = false;
                        }
                    }
                    else
                    {
                        Files.Enabled = false;
                        Submit.Visible = false;
                    }
                }
                //Manager control
                SPList listFunctions = CS2Web.GetList(Constants.LIST_FUNCTIONS);
                SPQuery queryFunction = new SPQuery();
                queryFunction.Query = String.Format(@"<Where>
	                    <Eq>
		                    <FieldRef Name='Members' LookupId='TRUE'/>
		                    <Value Type='User'>{0}</Value>
	                    </Eq>
                    </Where>", data.Reporter.Id);
                SPListItemCollection itemFunctions = listFunctions.GetItems(queryFunction);
                if (CS2SPQueryBuilder.HasItems(itemFunctions))
                {
                    SPFieldUserValueCollection lineManagers = CS2Convert.ToSPFieldUserValueCollection(itemFunctions[0]["Manager"]);
                    foreach (SPFieldUserValue manager in lineManagers)
                    {
                        if (manager.LookupId == CS2Web.CurrentUser.ID)
                        {
                            LineManagerComment.Enabled = true;
                            Approved.Visible = true;
                            Rejected.Visible = true;
                            break;
                        }
                    }
                }
                #endregion
            }
        }

        private void LoadDataReport(DailyReportItem data)
        {
            List<ProjectItem> workingProjects = new List<ProjectItem>();
            try
            {
                SPList listProject = CS2Web.GetList(Constants.LIST_PROJECTS);
                SPQuery queryWorkingProjects = new SPQuery();
                queryWorkingProjects.Query = String.Format(
                @"<Where>
                          <Or>
                             <And>
                                <IsNull>
                                   <FieldRef Name='Start' />
                                </IsNull>
                                <IsNull>
                                   <FieldRef Name='End' />
                                </IsNull>
                             </And>
                             <Or>
                                <Leq>
                                   <FieldRef Name='Start' />
                                   <Value IncludeTimeValue='FALSE' Type='DateTime'>{0}</Value>
                                </Leq>
                                <Geq>
                                   <FieldRef Name='End' />
                                   <Value IncludeTimeValue='FALSE' Type='DateTime'>{0}</Value>
                                </Geq>
                             </Or>
                          </Or>
                       </Where>", data.Date.ToString(CS2SPQueryBuilder.QUERY_DATE_FORMAT));
                SPListItemCollection itemProjects = listProject.GetItems(queryWorkingProjects);
                if (CS2SPQueryBuilder.HasItems(itemProjects))
                    foreach (SPListItem item in itemProjects)
                        workingProjects.Add(new ProjectItem { Item = item });
            }
            catch { }
            //Get report files
            try
            {
                SPList listDailyReportFiles = CS2Web.GetList(Constants.LIST_DAILY_REPORT_FILES);
                SPQuery queryDailyReportFiles = new SPQuery();
                queryDailyReportFiles.Query = String.Format(@"<Where>
                      <And>
	                     <Eq>
		                    <FieldRef Name='Date' />
		                    <Value IncludeTimeValue='FALSE' Type='DateTime'>{0}</Value>
	                     </Eq>
	                     <Eq>
		                    <FieldRef Name='Author' LookupId='TRUE'/>
		                    <Value Type='User'>{1}</Value>
	                     </Eq>
                      </And>
                    </Where>", data.Date.ToString(CS2SPQueryBuilder.QUERY_DATE_FORMAT), data.Reporter.Id);
                SPListItemCollection items = listDailyReportFiles.GetItems(queryDailyReportFiles);
                if (CS2SPQueryBuilder.HasItems(items))
                    foreach (SPListItem item in items)
                        data.ReportFiles.Add(new DailyReportFileItem().ReadItem(item));
            }
            catch { }
            Data = data;
            WorkingProjects = workingProjects;

            BindUserView();
            BindWorkingProjects();
            BindReportData();
        }

        private void BindReportData()
        {
            EmailTo.UpdateEntities(UserItem.GetEntitiesArrayList(Data.ReportTo));
            EmailCC.UpdateEntities(UserItem.GetEntitiesArrayList(Data.ReportCC));
            ReportDate.SelectedDate = Data.Date;
            Note.Text = Data.Note;
            LineManagerComment.Text = Data.LineManagerComment;
            Status.Text = Data.ReportStatus;
            Files.DataSource = Data.ReportFiles;
            Files.DataBind();
        }

        private void BindWorkingProjects()
        {
            Project.DataSource = WorkingProjects;
            Project.DataBind();
        }

        private void BindUserView()
        {
            Name.Text = Data.Reporter.Title;
            Code.Text = Data.Reporter.Code;
            Title.Text = Data.Reporter.JobTitle;
            Division.Text = Data.Reporter.Department;
            Region.Text = Data.Reporter.Region;
        }

        protected void Upload_Click(object sender, EventArgs e)
        {
            Save(false);
        }

        protected void Submit_Click(object sender, EventArgs e)
        {
            Save(true);
        }

        protected void Save(bool submitReport)
        {
            DateTime date = DateTime.Today;
            if (ReportDate.SelectedDate.HasValue)
            {
                date = ReportDate.SelectedDate.Value;
            }
            else
            {
                ReportDate.SelectedDate = date;
            }
            SPFieldLookupValueCollection fileLookup = new SPFieldLookupValueCollection();
            if (ReportFiles.UploadedFiles.Count > 0)
            {
                foreach (UploadedFile file in ReportFiles.UploadedFiles)
                {
                    try
                    {
                        int fileCounter = DailyFileCounts.FileInDate(date);
                        string destUrl = String.Format("{0}/{1}/D-{2}-{3}{4}", CS2Web.CurrentWeb.Url, Constants.LIST_DAILY_REPORT_FILES, date.ToString("ddMMyy"), fileCounter.ToString("000"), file.GetExtension());
                        SPFile fileAdded = CS2Web.CurrentWeb.Files.Add(destUrl, file.InputStream);
                        SPListItem fileItem = fileAdded.Item;
                        fileItem["Title"] = file.GetName();
                        fileItem["Date"] = date;
                        fileItem["Project"] = Project.SelectedValue;
                        fileItem["Note"] = file.GetFieldValue("Comment");
                        fileItem.SystemUpdate();
                        Data.ReportFiles.Add(new DailyReportFileItem().ReadItem(fileItem));
                    }
                    catch
                    {
                        SubmitMessage.Text += String.Format("<br/>Không thể tải tập tin '{0}', vui lòng thử lại!<br/>Problem upload file '{0}', please try again!", file.GetName());
                    }
                }
                Files.Rebind();
            }

            try
            {
                SPList listDailyReport = CS2Web.GetList(Constants.LIST_DAILY_REPORT);
                SPQuery query = new SPQuery();
                query.Query = String.Format(@"<Where>
                  <And>
                     <Eq>
                        <FieldRef Name='Title' />
                        <Value Type='Text'>{0}</Value>
                     </Eq>
	                <Eq>
		                <FieldRef Name='Author' LookupId='TRUE'/>
		                <Value Type='User'>{1}</Value>
	                </Eq>
                  </And>
               </Where>", date.ToString(Constants.DATE_FORMAT), Data.Reporter.Id);
                SPListItemCollection items = listDailyReport.GetItems(query);
                SPListItem item;
                if (CS2SPQueryBuilder.HasItems(items))
                {
                    item = items[0];
                }
                else
                {
                    item = listDailyReport.AddItem();
                    item["Title"] = date.ToString(Constants.DATE_FORMAT);
                }
                item["Note"] = Note.Text;
                SPFieldUserValueCollection reportTo = new SPFieldUserValueCollection();
                SPFieldUserValueCollection reportCC = new SPFieldUserValueCollection();
                MailAddressCollection To = new MailAddressCollection();
                MailAddressCollection CC = new MailAddressCollection();
                foreach (PickerEntity entity in EmailTo.ResolvedEntities)
                {
                    SPFieldUserValue fuv = new SPFieldUserValue(CS2Web.CurrentWeb, Convert.ToInt16(entity.EntityData[PeopleEditorEntityDataKeys.UserId]), entity.Description);
                    reportTo.Add(fuv);
                    To.Add(new MailAddress(fuv.User.Email, fuv.User.Name));
                }
                foreach (PickerEntity entity in EmailCC.ResolvedEntities)
                {
                    SPFieldUserValue fuv = new SPFieldUserValue(CS2Web.CurrentWeb, Convert.ToInt16(entity.EntityData[PeopleEditorEntityDataKeys.UserId]), entity.Description);
                    reportCC.Add(fuv);
                    CC.Add(new MailAddress(fuv.User.Email, fuv.User.Name));
                }
                item["ReportTo"] = reportTo;
                item["ReportCC"] = reportCC;
                item.SystemUpdate();
                
                SPList listDailyReportFiles = CS2Web.GetList(Constants.LIST_DAILY_REPORT_FILES);
                foreach (DailyReportFileItem file in Data.ReportFiles)
                {
                    try
                    {
                        SPListItem itemFile = listDailyReportFiles.GetItemById(file.Id);
                        itemFile["Title"] = file.Title;
                        itemFile["Note"] = file.Note;
                        itemFile["PMAproved"] = file.PMAproved;
                        itemFile["PMComment"] = file.PMComment;
                        itemFile.SystemUpdate();
                    }
                    catch { }
                }
                if (submitReport) SendMail(To, CC, "submit");
            }
            catch
            {
                SubmitMessage.Text += "<br/>Không thể lưu báo cáo, vui lòng thử lại!<br/>Problem save report, please try again!";
            }
            if(SubmitMessage.Text.Length == 0)
                SubmitMessage.Text = "<br/>Hoàn thành báo cáo!<br/>Report completed!";
            if (!submitReport) SubmitMessage.Text = "";
        }

        private void SendMail(MailAddressCollection To, MailAddressCollection CC, string action)
        {
            string subject = String.Format("[Daily Report] Report date '{0}' {1}", Data.Date.ToString(Constants.DATE_FORMAT), action);
            StringBuilder body = new StringBuilder();
            body.AppendFormat("<b>Reporter: </b>{0}<br/>", Data.Reporter.Title);
            body.AppendFormat("<b>Node: </b><br/>{0}<br/>", Data.Note);
            body.AppendFormat("<b>Updated by: </b>{0}<br/>", CS2Web.CurrentUser.Name);
            string url = Request.Url.AbsoluteUri;
            if (url.Contains('?')) url = url.Split('?')[0];
            body.AppendFormat("<b>Link: </b><a href='{0}?_Id={1}'>{0}?_Id={1}</a>", url.Replace(" ", "%20"), Data.Id);
            bool sendMailCompleted = CS2Web.SendEmailAttachments(To, CC, new MailAddressCollection(), subject, body.ToString());
            if (!sendMailCompleted)
                SubmitMessage.Text += "<br/>Lỗi gởi thư!/Error send mail!";
        }

        protected void Files_NeedDataSource(object sender, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
        {
            Files.DataSource = Data.ReportFiles;
        }

        protected void Files_ItemDeleted(object sender, GridCommandEventArgs e)
        {
            try
            {
                Hashtable rowItem = new Hashtable();
                ((GridEditableItem)e.Item).ExtractValues(rowItem);
                int id = CS2Convert.ToInt(rowItem["Id"]);
                SPList list = CS2Web.GetList(Constants.LIST_DAILY_REPORT_FILES);
                list.GetItemById(id).Delete();

                Response.Redirect(String.Format("{0}?_Id={1}", Request.Path, Data.Id));
            }
            catch { }
        }

        protected void Files_UpdateCommand(object sender, GridCommandEventArgs e)
        {
            Hashtable rowItem = new Hashtable();
            GridEditableItem editedItem = (GridEditableItem)e.Item;
            editedItem.ExtractValues(rowItem);
            rowItem["Title"] = (editedItem.FindControl("Title") as RadTextBox).Text;
            rowItem["Note"] = (editedItem.FindControl("Note") as RadTextBox).Text;
            rowItem["PMAprovedCheckBox"] = (editedItem.FindControl("PMAproved") as CheckBox).Checked;
            rowItem["PMComment"] = (editedItem.FindControl("PMComment") as RadTextBox).Text;

            int id = CS2Convert.ToInt(rowItem["Id"]);
            DailyReportFileItem fileItem = Data.ReportFiles.First(i => i.Id == id);
            fileItem.Title = CS2Convert.ToString(rowItem["Title"]);
            fileItem.Note = CS2Convert.ToString(rowItem["Note"]);
            fileItem.PMAproved = CS2Convert.ToBoolean(rowItem["PMAprovedCheckBox"]) ? "Aproved" : "Rejected";
            fileItem.PMComment = CS2Convert.ToString(rowItem["PMComment"]);
            Files.Rebind();
        }

        protected void ReportDate_SelectedDateChanged(object sender, Telerik.Web.UI.Calendar.SelectedDateChangedEventArgs e)
        {
            DailyReportItem data = new DailyReportItem();
            DateTime date = DateTime.Today;
            if (ReportDate.SelectedDate.HasValue)
            {
                date = ReportDate.SelectedDate.Value;
            }
            else
            {
                ReportDate.SelectedDate = date;
            }
            try
            {
                SPList listDailyReport = CS2Web.GetList(Constants.LIST_DAILY_REPORT);
                SPQuery query = new SPQuery();
                query.Query = String.Format(@"<Where>
                  <And>
                     <Eq>
                        <FieldRef Name='Title' />
                        <Value Type='Text'>{0}</Value>
                     </Eq>
	                <Eq>
		                <FieldRef Name='Author' LookupId='TRUE'/>
		                <Value Type='User'>{1}</Value>
	                </Eq>
                  </And>
               </Where>", date.ToString(Constants.DATE_FORMAT), Data.Reporter.Id);
                SPListItemCollection items = listDailyReport.GetItems(query);
                if (CS2SPQueryBuilder.HasItems(items))
                {
                    data.GetItem(items[0]);
                }
                else
                {
                    data.Date = date;
                    data.Reporter = Data.Reporter;
                }
            }
            catch
            {
                data.Date = date;
                data.Reporter = Data.Reporter;
            }
            LoadDataReport(data);
        }

        protected void Approved_Click(object sender, EventArgs e)
        {
            SaveLineManagerComment(true);
        }

        protected void Rejected_Click(object sender, EventArgs e)
        {
            SaveLineManagerComment(false);
        }

        private void SaveLineManagerComment(bool approved)
        {
            try
            {
                DateTime date = DateTime.Today;
                if (ReportDate.SelectedDate.HasValue) date = ReportDate.SelectedDate.Value;
                SPList listDailyReport = CS2Web.GetList(Constants.LIST_DAILY_REPORT);
                SPQuery query = new SPQuery();
                query.Query = String.Format(@"<Where>
                  <And>
                     <Eq>
                        <FieldRef Name='Title' />
                        <Value Type='Text'>{0}</Value>
                     </Eq>
	                <Eq>
		                <FieldRef Name='Author' LookupId='TRUE'/>
		                <Value Type='User'>{1}</Value>
	                </Eq>
                  </And>
               </Where>", date.ToString(Constants.DATE_FORMAT), Data.Reporter.Id);
                SPListItemCollection items = listDailyReport.GetItems(query);
                SPListItem item;
                if (CS2SPQueryBuilder.HasItems(items))
                {
                    item = items[0];
                }
                else
                {
                    item = listDailyReport.AddItem();
                    item["Title"] = date.ToString(Constants.DATE_FORMAT);
                }
                item["LineManagerComment"] = LineManagerComment.Text;
                item["Status"] = approved ? "Approved" : "Rejected";

                item.SystemUpdate();
                ActionMessage.Text = "<br/>Hoàn thành!<br/>Done!";
                //Send Mail
                MailAddressCollection To = new MailAddressCollection();
                MailAddressCollection CC = new MailAddressCollection();
                foreach (PickerEntity entity in EmailTo.ResolvedEntities)
                {
                    SPFieldUserValue fuv = new SPFieldUserValue(CS2Web.CurrentWeb, Convert.ToInt16(entity.EntityData[PeopleEditorEntityDataKeys.UserId]), entity.Description);
                    To.Add(new MailAddress(fuv.User.Email, fuv.User.Name));
                }
                foreach (PickerEntity entity in EmailCC.ResolvedEntities)
                {
                    SPFieldUserValue fuv = new SPFieldUserValue(CS2Web.CurrentWeb, Convert.ToInt16(entity.EntityData[PeopleEditorEntityDataKeys.UserId]), entity.Description);
                    CC.Add(new MailAddress(fuv.User.Email, fuv.User.Name));
                }
                SendMail(To, CC, approved ? "approved" : "rejected");
            }
            catch
            {
                ActionMessage.Text = "<br/>Có lỗi khi lưu ý kiến, vui lòng thử lại!<br/>Problem save comment, please try again!";
            }
        }
    }
}
